<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\DrainageLink\Action\Dashboard;

use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use MoChat\App\Common\Middleware\DashboardAuthMiddleware;
use MoChat\App\Rbac\Middleware\PermissionMiddleware;
use MoChat\App\User\Contract\UserContract;
use MoChat\App\WorkContact\Contract\WorkContactContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkContact\Contract\WorkContactRoomContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\App\WorkRoom\Contract\WorkRoomContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Request\ValidateSceneTrait;
use MoChat\Plugin\DrainageLink\Contract\DrainageLinkContactContract;
use MoChat\Plugin\DrainageLink\Contract\DrainageLinkContract;
use MoChat\Plugin\DrainageLink\Contract\DrainageLinkStatisticContract;

/**
 * 引流链接- 详情.
 *
 * Class Show.
 * @Controller
 */
class Show extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @var RequestInterface
     */
    protected $request;

    /**
     * @Inject
     * @var UserContract
     */
    protected $userService;

    /**
     * @Inject
     * @var DrainageLinkContract
     */
    protected $drainageLink;

    /**
     * @Inject
     * @var DrainageLinkStatisticContract
     */
    protected $drainageLinkStatistic;

    /**
     * @Inject
     * @var DrainageLinkContactContract
     */
    protected $drainageLinkContact;

    /**
     * @Inject
     * @var WorkContactContract
     */
    protected $workContact;

    /**
     * @Inject
     * @var WorkContactEmployeeContract
     */
    protected $workContactEmployee;

    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployee;

    /**
     * @Inject
     * @var WorkRoomContract
     */
    protected $workRoom;

    /**
     * @Inject
     * @var WorkContactRoomContract
     */
    protected $workContactRoom;

    /**
     * @Inject
     * @var StdoutLoggerInterface
     */
    private $logger;

    /**
     * @RequestMapping(path="/dashboard/drainageLink/show", methods="get")
     * @Middlewares({
     *     @Middleware(DashboardAuthMiddleware::class),
     *     @Middleware(PermissionMiddleware::class)
     * })
     * @return array 返回数组
     * @throws \JsonException
     */
    public function handle(): array
    {
        $user = user();
        // 判断用户绑定企业信息
        if (! isset($user['corpIds']) || count($user['corpIds']) !== 1) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }
        // 参数验证
        $this->validated($this->request->all());
        // 接收参数
        $id = (int) $this->request->input('id');
        // 查询数据
        return [
            'statistics' => $this->statistics($id),
            'contactAddDetail' => $this->contactAddDetail($id),
            'todayAddData' => $this->todayAddData($id),
        ];
    }

    protected function todayAddData(int $id): array
    {
        $todayAddData = $this->drainageLinkStatistic->getDrainageLinkStatisticsByLinkId($id, ['click_number', 'add_number', 'add_rate', 'created_at']);
        array_walk($todayAddData, function (&$item) {
            $item['createdAt'] = date('Y-m-d', strtotime($item['createdAt']));
        });
        return $todayAddData;
    }

    protected function statistics($id): array
    {
        $today = date('Y-m-d');
        $statistics['totalClickNumber'] = (int) $this->drainageLinkStatistic->sumDrainageLinkStatisticsByLinkId($id, 'click_number');
        $statistics['totalAddNumber'] = (int) $this->drainageLinkStatistic->sumDrainageLinkStatisticsByLinkId($id, 'add_number');
        $statistics['totalAddRate'] = $statistics['totalClickNumber'] > 0 ? (number_format($statistics['totalAddNumber'] / $statistics['totalClickNumber'], 2) * 100) . '%' : '0%';
        $todayData = $this->drainageLinkStatistic->getDrainageLinkStatisticsByLinkIdDay($id, $today, ['click_number', 'add_number', 'add_rate']);
        $statistics['todayClickNumber'] = $todayData['clickNumber'] ?? 0;
        $statistics['todayAddNumber'] = $todayData['addNumber'] ?? 0;
        $statistics['todayAddRate'] = $todayData['addRate'] ?? 0;
        return $statistics;
    }

    protected function contactAddDetail($linkId): array
    {
        $link = $this->drainageLink->getDrainageLinkById($linkId, ['type']);
        $contactList = $this->drainageLinkContact->getDrainageLinkContactByLinkId($linkId, ['contact_id', 'room_id', 'created_at']);
        foreach ($contactList as $k => $v) {
            $contact = $this->workContact->getWorkContactById($v['contactId'], ['corp_id', 'name']);
            if (empty($contact)) {
                $contactList[$k]['name'] = '未知';
                $contactList[$k]['employee'] = '未知';
                $contactList[$k]['status'] = 0;
            } else {
                $contactList[$k]['name'] = $contact['name'];
                if ($link['type'] === 1) {
                    $contactEmployee = $this->workContactEmployee->getWorkContactEmployeeByCorpIdContactId($v['contactId'], $contact['corpId'], ['employee_id', 'status']);
                    $contactList[$k]['employee'] = ! empty($contactEmployee['employeeId']) ? $this->workEmployee->getWorkEmployeeByIdWithTrashed($contactEmployee['employeeId'], ['name'])['name'] : '';
                    $contactList[$k]['status'] = $contactEmployee['status'] ?? 0;
                }
            }

            if ($link['type'] === 2) {
                $room = $this->workRoom->getWorkRoomById($v['roomId'], ['name']);
                $contactList[$k]['roomName'] = $room['name'] ?? '未知';
                $contactRoom = $this->workContactRoom->getWorkContactRoomByRoomIdContactId($v['roomId'], $v['contactId'], ['status']);
                $contactList[$k]['status'] = $contactRoom['status'] ?? '未知';
            }
        }
        return $contactList;
    }

    /**
     * 验证规则.
     *
     * @return array 响应数据
     */
    protected function rules(): array
    {
        return [
            'id' => 'required | integer | min:0 | bail',
        ];
    }

    /**
     * 验证错误提示.
     * @return array 响应数据
     */
    protected function messages(): array
    {
        return [
            'id.required' => '活动ID 必填',
            'id.integer' => '活动ID 必需为整数',
            'id.min  ' => '活动ID 不可小于1',
        ];
    }
}
